﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using UnityEngine;


namespace com.lib.manager
{
    public class DownLoadFileManager
    {

        public delegate void DownLoadFileManagerCallBack(DownLoadData data);

        private string _url = string.Empty;

        private int _lenth = 0;

        private string _savepath = string.Empty;

        private DownLoadData dd = new DownLoadData();

        private DownLoadFileManagerCallBack _call = null;

        public DownLoadFileManager(string url, int lenth, string savepath, DownLoadFileManagerCallBack call = null)
        {
            _url = url;
            _lenth = lenth;
            _savepath = savepath;
            _call = call;
        }

        private static Dictionary<string, Thread> data = new Dictionary<string, Thread>();

        /// <summary>
        /// 记录上次下载的数据
        /// </summary>
        private int _downlast = 0;


        private Timer temp = null;


        private static List<CallBcakHelp> savedata = new List<CallBcakHelp>();

        /// <summary>
        /// 计时,1S执行一次
        /// </summary>
        public void AddTimerData()
        {
            ///1s 执行一次
            temp = new Timer(TimerCallBack, "", 1000, 1000);

        }



        private void TimerCallBack(object o)
        {
            AddDonwloadgetData();
            //转成主线程里面进行完成
            CallBcakHelp ch = new CallBcakHelp();
            ch.call = _call;
            ch.dd = dd;
            ch.timer = temp;
            savedata.Add(ch);
        }

        public static void DesTory()
        {
            foreach (var key in data)
            {
                key.Value.Abort();
            }

        }

        public static void Update()
        {
            if (savedata.Count > 0)
            {
                CallBcakHelp ch = savedata[0];
                if (ch.call != null)
                {
                    ch.call(ch.dd);
                }
                if (ch.dd.finish)
                {
                    ch.timer.Dispose();
                }
                savedata.RemoveAt(0);

            }
        }


        /// <summary>
        /// 启动下载
        /// </summary>
        public bool Start()
        {
            if (!_url.StartsWith("http://"))
            {
                return false;
            }
            if (_lenth == 0)
            {
                return false;
            }
            if (data.ContainsKey(_url))
            {
                data[_url].Abort();
                data.Remove(_url);
            }
            AddTimerData();
            Thread t = new Thread(Download);
            t.Start();
            data.Add(_url, t);

            return true;
        }



        //每隔1S钟回调一次下载内容
        public void AddDonwloadgetData()
        {
            //计算出下载的速度  按KB 来计算
            int speeds = (int)((dd.currentLength - _downlast) / 1024);
            dd.speed = speeds;
            _downlast = dd.currentLength;
            //所有的数据都已经赋值完成
        }


        /// <summary>
        /// 启动下载
        /// </summary>
        private void Download()
        {
            HttpWebRequest hr = HttpWebRequest.Create(_url) as HttpWebRequest;
            HttpWebResponse hp = hr.GetResponse() as HttpWebResponse;
            Debug.Log(_lenth);
            dd.fileLength = _lenth;
            dd.finish = false;
            dd.currentLength = 0;
            ///获取缓存的流
            var stream = hp.GetResponseStream();
            byte[] buffer = new byte[_lenth];
            int temp = 0;

            int bufLen = _lenth > 1024 ? 1024 : _lenth;
            //每次写1024字节 1KB
            int size = stream.Read(buffer, 0, bufLen);  //size >0 还没有下载完成 =0 下载完毕  2000000000 2G
            FileStream fs = new FileStream(_savepath, FileMode.OpenOrCreate, FileAccess.Write); //建立一个写入流
            fs.Write(buffer, temp, bufLen);
            while (size > 0)
            {
                try
                {
                    dd.currentLength += bufLen;
                    bufLen = dd.fileLength - dd.currentLength > 1024 ? 1024 : dd.fileLength - dd.currentLength;
                    temp += 1024;
                    size = stream.Read(buffer, temp, bufLen);
                    fs.Write(buffer, temp, bufLen);
                    //得到最后一个下载的便宜
                }
                catch (System.Exception e)
                {
                    Debug.Log(e.Message);
                    break;
                }
            }
            Debug.Log("Finisgh1111111");
            dd.finish = true;
            if (dd.finish)
            {
                dd.currentLength = dd.fileLength;
            }
            fs.Close();
            stream.Close();

        }
    }

    //下载一个文件需要的基本参数:
    //1.文件的地址 http://gamecenter.ieasygp.com/download/mttt.apk
    //2.文件的大小 500KB 
    //3.下载文件的保存地址


    //回调所需要用的参数:
    //1.当前下载的进度
    //2.当前下载的速度
    //3.是否下载完成
    //4.文件的大小
    public class DownLoadData
    {
        // 百分比  10/500  
        public int currentLength { get; set; }

        public int speed { get; set; }

        public bool finish { get; set; }

        public int fileLength { get; set; }
    }

    public class CallBcakHelp
    {
        public DownLoadFileManager.DownLoadFileManagerCallBack call { get; set; }

        public DownLoadData dd { get; set; }

        public Timer timer { get; set; }
    }
}
